package com.qingyun.shop.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qingyun.common.constant.Constants;
import com.qingyun.common.constant.UserConstants;
import com.qingyun.common.core.domain.entity.SysUser;
import com.qingyun.common.core.domain.model.TiktokProxyVo;
import com.qingyun.common.core.mybatisplus.core.ServicePlusImpl;
import com.qingyun.common.core.page.TableDataInfo;
import com.qingyun.common.exception.ServiceException;
import com.qingyun.common.utils.PageUtils;
import com.qingyun.security.utils.SecurityUtils;
import com.qingyun.shop.domain.*;
import com.qingyun.shop.domain.bo.TiktokProxyBo;
import com.qingyun.shop.domain.vo.TiktokProxyTreeVo;
import com.qingyun.shop.mapper.TiktokProxyMapper;
import com.qingyun.shop.mapper.TiktokUserProxyMapper;
import com.qingyun.shop.mapper.TiktokUserShopMapper;
import com.qingyun.shop.service.ITiktokProxyBranchConfigService;
import com.qingyun.shop.service.ITiktokProxyService;
import com.qingyun.shop.service.ITiktokShopService;
import com.qingyun.shop.service.ITiktokTransferService;
import com.qingyun.system.domain.ProxyUserRequest;
import com.qingyun.system.mapper.SysUserMapper;
import com.qingyun.system.service.ISysUserService;
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.token.TokenService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 代理组织Service业务层处理
 *
 * @author qingyun
 * @date 2021-09-04
 */
@Service
public class TiktokProxyServiceImpl extends ServicePlusImpl<TiktokProxyMapper, TiktokProxy, TiktokProxyVo> implements ITiktokProxyService {

	@Autowired
	private MapperFacade mapperFacade;

	@Autowired
	private MapperFactory mapperFactory;

	@Autowired
	private TiktokUserProxyMapper tiktokUserProxyMapper;

	@Autowired
	private SysUserMapper sysUserMapper;

	@Autowired
	private ISysUserService userService;

	@Autowired
	private ITiktokShopService tiktokShopService;

	@Autowired
	private TiktokUserShopMapper tiktokUserShopMapper;

	@Autowired
	private ITiktokTransferService transferService;

	@Autowired
	private ITiktokProxyBranchConfigService tiktokProxyBranchConfigService;

    @Override
    public TiktokProxyVo queryById(Long id){
        return getVoById(id);
    }

	@Override
	public TableDataInfo<SysUser> selectPageUserList(ProxyUserRequest user) {
    	if(!SecurityUtils.isManager()){
    		user.setProxyId(SecurityUtils.getProxy().getId().longValue());
		}
		user.setUserType(Constants.PROXY_USER);
		return PageUtils.buildDataInfo(sysUserMapper.selectPageUserByProxyIdList(PageUtils.buildPage(), user));
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean insertProxyUserShop(SysUser user){
		userService.insertUser(user);
		TiktokProxy tiktokProxy = getById(user.getProxyId());
		if (ObjectUtil.isNull(tiktokProxy)) {
			return false;
		}
		//新增代理商和用户绑定
		TiktokUserProxy tiktokUserProxy = new TiktokUserProxy();
		tiktokUserProxy.setUserId(user.getUserId());
		tiktokUserProxy.setProxyId(tiktokProxy.getId());
		 tiktokUserProxyMapper.insert(tiktokUserProxy);


		TiktokShop one = tiktokShopService.lambdaQuery().eq(TiktokShop::getIsProxy, 1)
			.eq(TiktokShop::getProxyId, user.getProxyId()).one();
		if (ObjectUtil.isNotNull(one)) {
			//新增商户和上面用户绑定
			TiktokUserShop tiktokUserShop = new TiktokUserShop();
			tiktokUserShop.setUserId(user.getUserId());
			tiktokUserShop.setShopId(one.getId());
			tiktokUserShopMapper.insert(tiktokUserShop);
		}

		 return true;
	}

	@Override
    public List<TiktokProxyVo> queryTreeList(TiktokProxyBo bo){
		List<TiktokProxyVo> tiktokProxyVos = listVo(buildQueryWrapper(bo));
		Map<Long, List<TiktokProxyVo>> collect = tiktokProxyVos.stream().collect(Collectors.groupingBy((t) ->  t.getParentId()));
		if (CollectionUtil.isEmpty(collect)) {
			return new ArrayList<>();
		}
		List<TiktokProxyVo> tiktokProxy;
		if(!SecurityUtils.isManager()){
			tiktokProxy = collect.get(SecurityUtils.getProxy().getId());
		}else {
			tiktokProxy = collect.get(0L);
		}

		treeAdd(tiktokProxy,collect);
		List<TiktokProxyVo> tiktokProxyVo;
		if(!SecurityUtils.isManager()){
			List<TiktokProxyVo> userProxy = new ArrayList<>();
			TiktokProxyVo proxy = getVoById(SecurityUtils.getProxy().getId());
			proxy.setChildren(tiktokProxy);
			userProxy.add(proxy);
			tiktokProxyVo = mapperFacade.mapAsList(userProxy, TiktokProxyVo.class);
		}else{
			tiktokProxyVo = mapperFacade.mapAsList(tiktokProxy, TiktokProxyVo.class);
		}
		return tiktokProxyVo;
    }

    @Override
    public List<TiktokProxyTreeVo> queryPageList(TiktokProxyBo bo) {
		List<TiktokProxyVo> tiktokProxyVos = listVo(buildQueryWrapper(bo));
		if (CollectionUtil.isEmpty(tiktokProxyVos)) {
			return new ArrayList<>();
		}
		Map<Long, List<TiktokProxyVo>> collect = tiktokProxyVos.stream().collect(Collectors.groupingBy((t) ->  t.getParentId()));

		List<TiktokProxyVo> tiktokProxy;
		if(!SecurityUtils.isManager()){
			tiktokProxy = collect.get(SecurityUtils.getProxy().getId());
		}else {
			tiktokProxy = collect.get(0L);
		}

		treeAdd(tiktokProxy,collect);
		List<TiktokProxyTreeVo> tiktokProxyTreeVo;
		mapperFactory.classMap(TiktokProxyVo.class,TiktokProxyTreeVo.class).fieldMap("name","label").add().byDefault().register();
		MapperFacade mapperFacade=mapperFactory.getMapperFacade();
		if(!SecurityUtils.isManager()){
			List<TiktokProxyVo> userProxy = new ArrayList<>();
			TiktokProxyVo proxy = SecurityUtils.getProxy();
			proxy.setChildren(tiktokProxy);
			userProxy.add(proxy);
			tiktokProxyTreeVo = mapperFacade.mapAsList(userProxy, TiktokProxyTreeVo.class);
		}else{
			tiktokProxyTreeVo = mapperFacade.mapAsList(tiktokProxy, TiktokProxyTreeVo.class);
		}
		return tiktokProxyTreeVo;
    }

    public void treeAdd(List<TiktokProxyVo> tiktokProxyVos,Map<Long, List<TiktokProxyVo>> tiktokProxyVosMap){
		if (CollectionUtil.isEmpty(tiktokProxyVos)) {
			return ;
		}
          tiktokProxyVos.forEach((v)->{
			  List<TiktokProxyVo> nextProxyVos = tiktokProxyVosMap.get(v.getId());
			  if(CollectionUtil.isEmpty(nextProxyVos)){
                 return;
			  }
			 v.setChildren(nextProxyVos);
			  treeAdd(nextProxyVos,tiktokProxyVosMap);
		  });
	}

	@Override
	public Long selectProxyStatus(Long userId) {
		return baseMapper.selectProxyStatus(userId);
	}

	@Override
    public List<TiktokProxyVo> queryList(TiktokProxyBo bo) {
    	      if(!SecurityUtils.isManager()){
				  Long proxyId = SecurityUtils.getProxy().getId();
				  String format = StrUtil.format("  id IN ( SELECT id FROM tiktok_proxy WHERE id = {} or find_in_set( {} , ancestors ) )", proxyId, proxyId);
				  Map<String, Object> map = new HashMap<>();
				  map.put("dataScope",format);
				  bo.setParams(map);
			  }
        return listVo(buildQueryWrapper(bo));
    }

    private LambdaQueryWrapper<TiktokProxy> buildQueryWrapper(TiktokProxyBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TiktokProxy> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getParentId() != null, TiktokProxy::getParentId, bo.getParentId());
        lqw.like(StringUtils.isNotBlank(bo.getLeader()),TiktokProxy::getLeader,bo.getLeader());
        lqw.like(StringUtils.isNotBlank(bo.getName()), TiktokProxy::getName, bo.getName());
        lqw.orderByAsc(bo.getOrderNum() != null,TiktokProxy::getOrderNum);
        lqw.eq(bo.getStatus() != null, TiktokProxy::getStatus, bo.getStatus());
		if (params.containsKey("dataScope")) {
			lqw.apply((String) params.get("dataScope"));
		}
        return lqw;
    }

    //超级管理员可以任意新增
	//代理角色只能添加他的下级代理不能添加上级代理
	//最多新增三级代理
    @Override
	@Transactional
    public Boolean insertByBo(TiktokProxyBo bo) {
        TiktokProxy add = BeanUtil.toBean(bo, TiktokProxy.class);
        validEntityBeforeSave(add);
		TiktokProxy parentProxy = getById(add.getParentId());
		if (UserConstants.DEPT_DISABLE.equals(parentProxy.getStatus())) {
			throw new ServiceException("代理停用，不允许新增");
		}
		add.setCreateBy(SecurityUtils.getUsername());
		add.setAncestors(parentProxy.getAncestors()+","+add.getParentId());
		boolean save = save(add);

		//默认配置
		TiktokProxyBranchConfig config=new TiktokProxyBranchConfig();
		config.setProxyId(add.getId());
		config.setProxyPrice(new BigDecimal(1));
		config.setOneProxyRatio(new BigDecimal(0.2));
		config.setTowProxyRatio(new BigDecimal(0.3));
		tiktokProxyBranchConfigService.save(config);

        //代理商并且新增商户
		//新增默认商户
		TiktokShop tiktokShop = new TiktokShop();
		tiktokShop.setProxyId(add.getId());
		tiktokShop.setProxyName(add.getName());
		tiktokShop.setPic(bo.getPic());
		tiktokShop.setName(add.getName());
		tiktokShop.setLeader(add.getLeader());
		tiktokShop.setOrderNum(0);
		tiktokShop.setIsProxy(1);
		tiktokShop.setBusinessTime("07:00-19:00");
		tiktokShop.setPhone(add.getPhone());
		tiktokShop.setCreateBy(SecurityUtils.getUsername());
		tiktokShopService.save(tiktokShop);
		add.setShopId(tiktokShop.getId());
		updateById(add);

		return save;
    }



    @Override
    public Boolean updateByBo(TiktokProxyBo bo) {
        TiktokProxy update = BeanUtil.toBean(bo, TiktokProxy.class);
        return updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(TiktokProxy entity){
			AtomicInteger atomicInteger=new AtomicInteger(0);
			if(!entity.getParentId().equals(0L)){
				List<TiktokProxyVo> tiktokProxyVos = listVo();
				treeCascade(entity.getParentId(),tiktokProxyVos,atomicInteger);
				if(atomicInteger.get()>=3){
					throw new ServiceException("最多新增三层代理");
				}
			}
    }

	public void treeCascade(Long parentId,List<TiktokProxyVo> tiktokProxyVos,AtomicInteger atomicInteger){
		tiktokProxyVos.forEach((k)->{
			if (k.getId().equals(parentId)) {
				atomicInteger.incrementAndGet();
				treeCascade(k.getParentId(),tiktokProxyVos,atomicInteger);
			}
		});
	}
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid,Boolean inherit) {
        if(isValid){
			ids.forEach(id->{
				TiktokProxyVo tiktokProxyVo = queryById(id);
				int count = count(Wrappers.lambdaQuery(TiktokProxy.class).eq(TiktokProxy::getParentId, tiktokProxyVo.getId()));
				if(count>0){
					throw new ServiceException("请先删除子栏目");
				}
				LambdaQueryWrapper<TiktokUserProxy> updateWrapper = Wrappers.lambdaQuery(TiktokUserProxy.class)
					.eq(TiktokUserProxy::getProxyId, id);
				//代理商用户继承
				if(tiktokProxyVo!=null&& inherit) {
					//继承代理商下的用户
					TiktokUserProxy tiktokUserProxy = new TiktokUserProxy();
					tiktokUserProxy.setProxyId(tiktokProxyVo.getParentId());
					tiktokUserProxyMapper.update(tiktokUserProxy, updateWrapper);
					//继承代理商下的商户
					tiktokShopService.update(Wrappers.lambdaUpdate(TiktokShop.class).set(TiktokShop::getProxyId,tiktokProxyVo.getParentId()).eq(TiktokShop::getProxyId,id));
				}else{
					List<TiktokUserProxy> tiktokUserProxies = tiktokUserProxyMapper.selectList(updateWrapper);
					Set<Long> collect = tiktokUserProxies.stream().map(TiktokUserProxy::getUserId).collect(Collectors.toSet());
					if(CollectionUtil.isNotEmpty(collect)){
						userService.remove(Wrappers.lambdaQuery(SysUser.class).in(SysUser::getUserId,collect));
					}
                   //删除代理商下商户和代理商用户
					List<TiktokShop> list = tiktokShopService.list(Wrappers.lambdaQuery(TiktokShop.class).eq(TiktokShop::getProxyId, id));
					if(CollectionUtil.isNotEmpty(list)){
						List<Long> shopIds = list.stream().map((shop) -> shop.getId()).collect(Collectors.toList());
						List<TiktokUserShop> tiktokUserShops = tiktokUserShopMapper.selectList(Wrappers.lambdaQuery(TiktokUserShop.class).in(TiktokUserShop::getShopId, shopIds));
						if(CollectionUtil.isNotEmpty(tiktokUserShops)){
							List<Long> userids = tiktokUserShops.stream().map((shops) -> shops.getUserId()).collect(Collectors.toList());
							userService.remove(Wrappers.lambdaQuery(SysUser.class).in(SysUser::getUserId,userids));
						}
					}

				}
			});
        }
        return removeByIds(ids);
    }

	@Override
	public Boolean transfer(Long shopId, Long videoCount) {
		if (SecurityUtils.isProxy()) {
			if (videoCount<=0) {
				return false;
			}
			Long id = SecurityUtils.getProxy().getId();
			TiktokProxy tiktokProxy = getById(id);
			if (tiktokProxy.getVideoCount()<=0||tiktokProxy.getVideoCount()<videoCount) {
				throw new ServiceException("代理商余额不足");
			}
			tiktokProxy.setVideoCount(tiktokProxy.getVideoCount() - videoCount);
			updateById(tiktokProxy);
			TiktokShop tiktokshop = tiktokShopService.getById(shopId);
			tiktokshop.setVideoCount(tiktokshop.getVideoCount() + videoCount);
			tiktokShopService.updateById(tiktokshop);

			TiktokTransfer tiktokTransfer = new TiktokTransfer();
			tiktokTransfer.setCreateTime(new Date());
			tiktokTransfer.setProxyId(tiktokProxy.getId());
			tiktokTransfer.setProxyName(tiktokProxy.getName());
			tiktokTransfer.setShopId(tiktokshop.getId());
			tiktokTransfer.setShopName(tiktokshop.getName());
			tiktokTransfer.setVideoCount(String.valueOf(videoCount));
			transferService.save(tiktokTransfer);


			return true;
		}
		return false;
	}


	@Override
	public TiktokProxy selectProxyByUserId(Long userId) {
		TiktokUserProxy tiktokUserProxy = tiktokUserProxyMapper.selectOne(Wrappers.lambdaQuery(TiktokUserProxy.class).eq(TiktokUserProxy::getUserId, userId));
		if (tiktokUserProxy==null) {
			throw new ServiceException("代理商不存在");
		}
		return getById(tiktokUserProxy.getProxyId());
	}

	/**
	 * 获取代理商的视频转发余额
	 */
	@Override
	public Long selectVideoCount() {

		if (SecurityUtils.isManager()) {
			return 9999999L;
		}

		Long id = SecurityUtils.getProxy().getId();
		TiktokProxy tiktokProxy = getById(id);
		return tiktokProxy.getVideoCount();
	}
}
